﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

namespace Extend.Pool
{
    public class ReferencePool : PoolBase
    {
        public override int CountUnUsed { get { return _pool.Count; } protected set { return; } }

        protected Stack<object> _pool = new Stack<object>();
        protected Type _referenceType;

        public ReferencePool(Type type)
        {
            _referenceType = type;
            Capacity = int.MaxValue;
            Name = type.Name;
        }

        public T Spawn<T>() where T : class
        {
            CheckType<T>();

            T result = null;
            lock (_pool)
            {
                if (_pool.Count > 0)
                {
                    result = _pool.Pop() as T;
                }
            }
            if (result == null)
            {
                result = CreateInstance(typeof(T)) as T;
                Count++;
            }
            return result;
        }

        public void Recycle<T>(T obj) where T : class
        {
            CheckType<T>();

            if (obj == null)
            {
                return;
            }
            lock (_pool)
            {
                if (_pool.Count < Capacity)
                {
                    _pool.Push(obj);
                }
                else
                {
                    Count--;
                }
            }
        }

        public override void ReleaseUnused()
        {
            lock (_pool)
            {
                _pool.Clear();
            }
        }

        private void CheckType<T>()
        {
            if (typeof(T) != _referenceType)
            {
                throw new System.Exception("Type is Wrong");
            }
        }

        private object CreateInstance(Type t)
        {
            if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                t = Nullable.GetUnderlyingType(t);
            }
            return Activator.CreateInstance(t, true);
        }
    }
}

